package com.wxh.bomb.netty.myrpc.utils;

import com.wxh.bomb.netty.myrpc.annotation.Service;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * 类扫描
 *
 * @author wxh
 */
public class ServiceScaner {

    /**
     * 扫描服务
     * @return
     */
    public static List<Class> scanService() {
        // 扫描服务下所有的类
        List<Class> classes = scanClass("");

        // 过滤服务
        List<Class> service = new ArrayList<Class>();
        for (Class clz : classes) {
            if (clz.isAnnotationPresent(Service.class)) {
                service.add(clz);
            }
        }
        return service;
    }

    /**
     * 扫描包下的类
     * @param basePkg
     * @return
     */
    public static List<Class> scanClass(String basePkg) {
        // 包名转换为路径
        String classpath = ServiceScaner.class.getResource("/").getPath();
        String searchPath = classpath + basePkg.replace(".", File.separator);

        List<String> classPaths = searchPath(new File(searchPath));

        // 反射获得类对象
        List<Class> classes = new ArrayList<Class>();
        for (String clzName: classPaths) {
            clzName = clzName.replace(classpath.replace("/","\\").replaceFirst("\\\\",""),"").replace("\\",".").replace(".class","");
            Class cls = null;
            try {
                cls = Class.forName(clzName);
            } catch (ClassNotFoundException e) {
                System.out.println(clzName + "加载失败\n" + e.getLocalizedMessage());
            }
            classes.add(cls);
        }
        return classes;
    }

    /**
     * 该方法会得到所有的类
     * @param file
     */
    private static List<String> searchPath(File file) {
        // 扫描到的类
        List<String> classPaths = new ArrayList<String>();
        if (file.isDirectory()) {// 文件夹递归
            File[] files = file.listFiles();
            for (File f1 : files) {
                classPaths.addAll(searchPath(f1));
            }
        } else {//标准文件
            //标准文件我们就判断是否是class文件
            if (file.getName().endsWith(".class")) {
                classPaths.add(file.getPath());
            }
        }
        return classPaths;
    }
}
